package ws.service.database;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import ws.service.Categoria;

public class CategoriaDAO {
	private Connection connection;
	
// Construtores
	public CategoriaDAO() {
		try {
			this.connection = new ConnectionFactory().getConnection();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	public CategoriaDAO(Connection connection) {
		this.connection = connection;
	}
	
// Obtem uma categoria para um dado id
	public Categoria consulta(Short id) {
		String sql = "select * from Categoria where idCategoria = ?";
		try {
			Categoria categoria = new Categoria();
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			
			stmt.setShort(1, id);
			ResultSet rs = stmt.executeQuery();
			
			if (rs.next()) {
				categoria.setId(rs.getShort("idCategoria"));
				categoria.setNome(rs.getString("nomeCategoria"));
				categoria.setPai(rs.getShort("categoriaPai"));
			}
			rs.close();
			stmt.close();
			
			return categoria;
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
// Adiciona categoria no banco de dados
	public void adiciona(Categoria categoria) {
		try {
			Short i, j = null, k = null;
			Categoria[] lista = new CategoriaDAO().getLista();
			
			for (i = 0; i < lista.length; i++) {
				if (lista[i].getId() != i)
					if (j == null) j = i;
				if (lista[1].getId() == categoria.getPai()) k = i;
			}
			if (j == null) j = i;
			if (k == null) System.out.println("Adiciona: Categoria pai não existe!");
			else {
				j = categoria.getId();
				String sql = "insert into Categoria (idCategoria, nomeCategoria, categoriaPai) values (?,?,?)";
				PreparedStatement stmt = connection.prepareStatement(sql);
				
				stmt.setShort(1, categoria.getId());
				stmt.setString(2, categoria.getNome());
				stmt.setShort(3, categoria.getPai());
				
				stmt.execute();
				stmt.close();
			}
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
// Exclui categoria do banco de dados
	public void exclui(Short id) {
		String sql = "delete from Categoria where idCategoria = ?";
		try {
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			
			stmt.setShort(1, id);
			
			stmt.execute();
			stmt.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
// Atualiza categoria no banco de dados
	public void atualiza(Short id, String nome, Short pai) {
		try {
			Short i, j = null, k = null;
			Categoria[] lista = new CategoriaDAO().getLista();
			
			for (i = 0; i < lista.length; i++) {
				if (lista[i].getId() == id) j = i;
				if (lista[i].getId() == pai) k = i;
			}
			if (j == null) System.out.println("Atualiza: Categoria inválida!");
			else if (k == null) System.out.println("Atualiza: Categoria pai inválida!");
			else if (id == pai) System.out.println("Atualiza: Categoria deve ser diferente da categoria pai!");
			else if (lista[k].getPai() == lista[j].getId()) System.out.println("Atualiza: Categoria não pode ser pai da categoria pai!");
			else {
				String sql = "update Categoria set nomeCategoria = ?, categoriaPai = ? where idCategoria = ?";
				PreparedStatement stmt = this.connection.prepareStatement(sql);
				
				stmt.setString(1, nome);
				stmt.setShort(2, pai);
				stmt.setShort(3, lista[j].getId());
				
				stmt.execute();
				stmt.close();
			}
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
// Obtem lista completa de categorias
	public Categoria[] getLista() {
		String sql = "select * from Categoria";
		try {
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			ResultSet rs = stmt.executeQuery();
			
			rs.last();
			int nRecords = rs.getRow();
			Categoria[] categorias = new Categoria[nRecords];
			rs.beforeFirst();
			
			int count = 0;
			while(rs.next()) {
				Categoria categoria = new Categoria();
				categoria.setId(rs.getShort("idCategoria"));
				categoria.setNome(rs.getString("nomeCategoria"));
				categoria.setPai(rs.getShort("categoriaPai"));
				categorias[count] = categoria;
				count++;
			}
			rs.close();
			stmt.close();
			return categorias;
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
// Obtem lista de subcategorias para uma dada categoria
	public Categoria[] getSubLista(Short id) {
		String sql = "select * from Categoria where categoriaPai = ?";
		try {
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			stmt.setShort(1, id);
			ResultSet rs = stmt.executeQuery();
			
			rs.last();
			int nRecords = rs.getRow();
			Categoria[] categorias = new Categoria[nRecords];
			rs.beforeFirst();
			
			int count = 0;
			while(rs.next()) {
				Categoria categoria = new Categoria();
				categoria.setId(rs.getShort("idCategoria"));
				categoria.setNome(rs.getString("nomeCategoria"));
				categoria.setPai(rs.getShort("categoriaPai"));
				categorias[count] = categoria;
				count++;
			}
			rs.close();
			stmt.close();
			return categorias;
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}
